#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Ticker.h>

char auth[] = "1a186d1f3d9f";
char ssid[] = "zhouliangan44";
char pswd[] = "wxg13948532823";

const long utcOffsetInSeconds = 8 * 3600;  // 设置时区偏移量，这里是 GMT+8 (北京时间)

#define Sw1 D0
#define Sw2 D1
#define Sw3 D2
#define Sw4 D5
#define L1 10
#define L2 D6
#define L3 D7
#define FS_MOUNT_POINT "/data"

#define timeinterrupt_gap 30 * 1000

bool sb1, sb2, sb3, sb4;
bool li1, li2, li3;
int restime = 1212;  // 每天12:12分重启
int autoopentime = 1112;
int autoclosetime = 2300;
bool auto_close_open = 0;  // 默认关闭
uint8_t hour;
uint8_t minute;
uint8_t sec;
uint8_t days_had_ran;
int inittime=0;
// WiFi连接状态标志位
bool wifiConnected = 1;

bool auto_rst = 1;
bool admit = 1;
bool judje_for_gain_time = 0;        // 表示没有获取到时间
bool judje_for_soft_auto_open = 1;   // avoid in a time reset all time
bool judje_for_soft_auto_close = 1;  // avoid in a time reset all time
bool add_day_detact = 0;

ESP8266WebServer esp8266_server(80);  // 建立ESP8266WebServer对象，该对象用于响应HTTP请求。监听端口（80）
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
Ticker timer;

void detactswitch();
#include "wifi.h"

void setup() {
  // put your setup code here, to run once:
  pinMode(L1, OUTPUT);
  pinMode(L2, OUTPUT);
  pinMode(L3, OUTPUT);

  digitalWrite(L1, 1);  // 由于上电时所有IO都是高电平，如此防止灯闪一下
  digitalWrite(L2, 1);
  digitalWrite(L3, 1);

  pinMode(Sw4, INPUT_PULLUP);
  pinMode(Sw1, INPUT_PULLUP);
  pinMode(Sw3, INPUT_PULLUP);
  pinMode(Sw2, INPUT_PULLUP);

  Serial.begin(115200);
  Serial.println("open````");

  pinMode(L1, OUTPUT);
  pinMode(L2, OUTPUT);
  pinMode(L3, OUTPUT);
  pinMode(Sw4, INPUT_PULLUP);
  pinMode(Sw1, INPUT_PULLUP);
  pinMode(Sw3, INPUT_PULLUP);
  pinMode(Sw2, INPUT_PULLUP);

  sb1 = digitalRead(Sw1);  // 读取按钮状态
  sb2 = digitalRead(Sw2);  // 读取按钮状态
  sb3 = digitalRead(Sw3);  // 读取按钮状态
  sb4 = digitalRead(Sw4);  // 读取按钮状态

  if (SPIFFS.begin()) {  // 启动闪存文件系统
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }

  delay(2000);  // 等待系统完成初始化
  // 上电后读取复位前的数据
  File file = SPIFFS.open(FS_MOUNT_POINT "/data.txt", "r");

  if (!file) {
    Serial.println("无法打开文件！");
    return;
  }
  // 读取布尔变量的值
  li1 = file.readStringUntil('\n').toInt();
  li2 = file.readStringUntil('\n').toInt();
  li3 = file.readStringUntil('\n').toInt();
  auto_close_open = file.readStringUntil('\n').toInt();
  admit = file.readStringUntil('\n').toInt();
  wifiConnected = file.readStringUntil('\n').toInt();
  auto_rst = file.readStringUntil('\n').toInt();

  // 读取整型变量的值
  int intValue1 = file.readStringUntil('\n').toInt();
  int intValue2 = file.readStringUntil('\n').toInt();
  int intValue3 = file.readStringUntil('\n').toInt();

  restime = intValue1;
  autoopentime = intValue2;
  autoclosetime = intValue3;

  Serial.println("READ SUCCESSDULLY");
  Serial.println(li1);
  Serial.println(li2);
  Serial.println(li3);
  Serial.println(auto_close_open);
  Serial.println(admit);
  Serial.printf("wificonnected:%d\n", wifiConnected);

  // Serial.println(intValue1);
  // Serial.println(intValue2);
  // Serial.println(intValue3);
  Serial.println(restime);
  Serial.println(autoopentime);
  Serial.println(autoclosetime);

  // 关闭文件
  file.close();

  initWeb();
  if (wifiConnected) {
    timeClient.begin();
  }
  // timer.attach_ms(timeinterrupt_gap, timerISR);

  delay(3000);
  digitalWrite(L1, li1);
  digitalWrite(L2, li2);
  digitalWrite(L3, li3);
}

void loop() {
  if (wifiConnected) {
    esp8266_server.handleClient();  // 处理网络请求
    timeClient.update();
  }
//  if (!judje_for_gain_time && wifiConnected)  // wifi连接并且没有获取到正确时间调用
//  {
//    timeClient.update();
//    inittime = timeClient.getHours() * 100 + timeClient.getMinutes();
//    Serial.printf("启动时间：%d", inittime);
//    if (inittime != 800)
//      judje_for_gain_time = 1;
//  }
  if (wifiConnected) {
    hour = timeClient.getHours();
    minute = timeClient.getMinutes();
    sec = timeClient.getSeconds();
  }

  if (restime == hour * 100 + minute && auto_rst && wifiConnected && sec <= 1)  // 如果wifi连接才能获取到即刻时间才能进行此判断
  {
    digitalWrite(L1, 1);  // 先拉高防止待会闪烁
    digitalWrite(L2, 1);
    digitalWrite(L3, 1);

    Serial.println("restime");  // for test
    // 创建文件
    File file = SPIFFS.open(FS_MOUNT_POINT "/data.txt", "w");

    if (!file) {
      Serial.println("无法创建文件！");
      return;
    }
    // 将变量的值写入文件
    file.println(li1 ? "1" : "0");
    file.println(li2 ? "1" : "0");
    file.println(li3 ? "1" : "0");
    file.println(auto_close_open ? "1" : "0");
    file.println(admit ? "1" : "0");
    file.println(wifiConnected ? "1" : "0");
    file.println(auto_rst ? "1" : "0");

    String intValue1 = String(restime);
    String intValue2 = String(autoopentime);
    String intValue3 = String(autoclosetime);

    file.println(intValue1);
    file.println(intValue2);
    file.println(intValue3);
    // 关闭文件
    file.close();
    Serial.println("数据已成功写入文件！");

    ESP.reset();
  }
  if (auto_close_open && wifiConnected)  // 如果wifi连接才能获取到即刻时间才能进行此判断
  {
    if (autoopentime == hour * 100 + minute && judje_for_soft_auto_open) {
      li2 = 1;
      Serial.println("opentime");    // for test
      judje_for_soft_auto_open = 0;  // to realize just run once
    }
    if (autoclosetime == hour * 100 + minute && judje_for_soft_auto_close) {
      li2 = 0;
      Serial.println("closetime");    // for test
      judje_for_soft_auto_close = 0;  // to realize just run once
    }
    if (autoopentime != hour * 100 + minute)
      judje_for_soft_auto_open = 1;
    if (autoclosetime != hour * 100 + minute)
      judje_for_soft_auto_close = 1;
  }

  if (30 == minute) {  // 每30min记录一次数据
    // 创建文件
    File file = SPIFFS.open(FS_MOUNT_POINT "/data.txt", "w");

    if (!file) {
      Serial.println("无法创建文件！");
      return;
    }
    // 将变量的值写入文件
    file.println(li1 ? "1" : "0");
    file.println(li2 ? "1" : "0");
    file.println(li3 ? "1" : "0");
    file.println(auto_close_open ? "1" : "0");
    file.println(admit ? "1" : "0");
    file.println(wifiConnected ? "1" : "0");
    file.println(auto_rst ? "1" : "0");

    String intValue1 = String(restime);
    String intValue2 = String(autoopentime);
    String intValue3 = String(autoclosetime);

    file.println(intValue1);
    file.println(intValue2);
    file.println(intValue3);
    // 关闭文件
    file.close();
    Serial.println("数据已成功写入文件！");
  }

  if (inittime == hour * 100 + minute && sec <= 0) {
    if (add_day_detact) {
      days_had_ran++;
      add_day_detact = 0;
    }
  } else
    add_day_detact = 1;
  detactwifi();
  detactswitch();
}

void detactswitch() {
  bool b1 = digitalRead(Sw1);  // 读取按钮状态
  bool b2 = digitalRead(Sw2);  // 读取按钮状态
  bool b3 = digitalRead(Sw3);  // 读取按钮状态
  bool b4 = digitalRead(Sw4);  // 读取按钮状态

  if (sb1 != b1) {
    delay(100);
    if (sb1 != b1) {
      // digitalWrite(L1,!digitalRead(L1));
      li1 = !li1;
      sb1 = b1;
    }
  }
  if (sb2 != b2) {
    delay(100);
    if (sb2 != b2) {
      li1 = !li1;
      sb2 = b2;
    }
  }
  if (sb3 != b3) {
    delay(100);
    if (sb3 != b3) {
      // digitalWrite(L2,!digitalRead(L2));
      sb3 = b3;
      li2 = !li2;
    }
  }

  if (sb4 != b4) {
    delay(100);
    if (sb4 != b4) {
      // digitalWrite(L3,!digitalRead(L3));
      sb4 = b4;
      li3 = !li3;
    }
  }

  digitalWrite(L1, li1);
  digitalWrite(L2, li2);
  digitalWrite(L3, li3);
}

void detactwifi() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi disconnected!");
    wifiConnected = 0;
    Serial.printf("wificonnected:%d\n", wifiConnected);  // for test
  } else
    wifiConnected = 1;
}
